import { Store } from 'vuex';
import axios from 'axios';
import Router from 'vue-router';
import i18n from '@/locale';
import { Environment } from '@/environments/environment';
import { AppService } from '@/studio-core/service/app-service/AppService';

/**
 * 拦截器
 *
 * @export
 * @class Interceptors
 */
export class Interceptors {
    /**
     * 路由对象
     *
     * @private
     * @type {(Router | any)}
     * @memberof Interceptors
     */
    private router: Router | any;

    /**
     * 缓存对象
     *
     * @private
     * @type {(Store<any> | any)}
     * @memberof Interceptors
     */
    private store: Store<any> | any;

    /**
     * 应用服务
     *
     * @private
     * @memberof Interceptors
     */
    private appService = new AppService();

    /**
     *  单列对象
     *
     * @private
     * @static
     * @type {LoadAppData}
     * @memberof Interceptors
     */
    private static readonly instance: Interceptors = new Interceptors();

    /**
     * Creates an instance of Interceptors.
     * 私有构造，拒绝通过 new 创建对象
     *
     * @memberof Interceptors
     */
    private constructor() {
        if (Interceptors.instance) {
            return Interceptors.instance;
        } else {
            this.intercept();
        }
    }

    /**
     * 获取 LoadAppData 单例对象
     *
     * @static
     * @param {Router} route
     * @param {Store<any>} store
     * @returns {Interceptors}
     * @memberof Interceptors
     */
    public static getInstance(route: Router, store: Store<any>): Interceptors {
        this.instance.router = route;
        this.instance.store = store;
        return this.instance;
    }

    /**
     * 拦截器实现接口
     *
     * @private
     * @memberof Interceptors
     */
    private intercept(): void {
        axios.interceptors.request.use(
            (config: any) => {
                if (this.router) {
                    const appdata = this.store.getters.getAppData();
                    if (appdata) {
                        const { context, headers } = appdata;
                        if (context?.srforgsectorid) {
                            config.headers.srforgsectorid = context.srforgsectorid;
                        }
                        if (headers && headers instanceof Object) {
                            Object.assign(config.headers, headers);
                        }
                    }
                }
                const token = this.appService.getToken();
                if (isExistAndNotEmpty(token)) {
                    config.headers.Authorization = `Bearer ${token}`;
                }
                config.headers['Accept-Language'] = i18n.locale;
                if (
                    !Object.is(Environment.BaseUrl, '') &&
                    !config.url.startsWith('https://') &&
                    !config.url.startsWith('http://') &&
                    !config.url.startsWith('./assets')
                ) {
                    config.url = Environment.BaseUrl + config.url;
                }
                return config;
            },
            (error: any) => {
                return Promise.reject(error);
            }
        );

        axios.interceptors.response.use(
            (response: any) => {
                if(response.headers && response.headers['refreshtoken'] && this.appService.getToken()){
                    this.appService.refreshToken(response);
                }    
                return response;
            },
            (error: any = { response: {} }) => {
                const res = error.response;
                // 处理异常
                if (res.headers && res.headers['x-ibz-error']) {
                    res.data.errorKey = res.headers['x-ibz-error'];
                }
                if (res.headers && res.headers['x-ibz-params']) {
                    res.data.entityName = res.headers['x-ibz-params'];
                }
                const _data = res.data;
                // 401认证已过期，或未认证
                if (res.status === 401) {
                    this.appService.doLogin(_data.data);
                } else if (res.status === 403) {
                    if (res.data && res.data.status && Object.is(res.data.status, 'FORBIDDEN')) {
                        const alertMessage: string = '非常抱歉，您无此操作权限，如需操作请联系管理员！';
                        Object.assign(res.data, { localizedMessage: alertMessage, message: alertMessage });
                    }
                }
                return Promise.reject(res);
            }
        );
    }
}
